Skip to content

feat: implement PHP clone — parser, checker, EIR shallow object copy#472

Closed
chadmandoo wants to merge 1 commit into
illegalstudio:mainfrom
chadmandoo:upstream-pr/clone-operator
Closed

feat: implement PHP clone — parser, checker, EIR shallow object copy#472
chadmandoo wants to merge 1 commit into
illegalstudio:mainfrom
chadmandoo:upstream-pr/clone-operator

Conversation

@chadmandoo

Copy link
Copy Markdown
Contributor

Implements clone $expr end-to-end:

  • PARSER: contextual recognition — an identifier spelled clone in prefix position followed by an operand-start token parses as a unary operator; clone stays fully usable as a method name and clone($x) lands on the operator like PHP.
  • AST: ExprKind::Clone with arms across every expression walker (resolver, optimizer passes, preludes, usage collectors, parser dependency walks); effects mirror ObjectNew.
  • CHECKER: the operand must be a statically-typed object; the result is the same class. Classes declaring __clone() are rejected explicitly ("__clone() hooks are not supported yet") rather than silently skipping the hook.
  • EIR: Op::ObjectCloneShallow — the backend allocates a same-class payload (heap-kind stamp + class-id word) and copies the statically-sized payload wordwise. Reference-property slots copy their CELL POINTER, matching PHP (a reference property stays shared with the original); dynamic-properties classes are rejected (a payload copy would share the dynamic-prop hash).

Byte-parity vs PHP 8.5: the PSR-7 withX() immutability round-trip (original untouched, clone mutated, object slot shared) and contextual-keyword probes. 2 regression tests.

chadmandoo added a commit to chadmandoo/elephc that referenced this pull request Jul 10, 2026
….1 (R6/#595)

Three v0.26.0 enum/parser fixes, survey-driven (79% → 85%, 241 → 262/307):

- ENUM-CASE PARAM DEFAULT (illegalstudio#468, declarations.rs): `E $x = E::Case` — an
  enum-case default has the enum object type, but syntactic inference types
  every `::` access as Str. When the declared type is Object(E) and the
  default is a scoped access naming E, accept it (the semantic pass validates
  the case exists). Clears the Badge/Button `$variant expects Object, got Str`
  family (9).
- KEYWORD ENUM-CASE NAMES (body.rs): PHP 8 allows semi-reserved keywords as
  enum-case names (`case Default;`, `case String;`, `case Float;`) — every one
  but `class` (reserved for `Foo::class`). Clears CardVariant/LogicalType/
  HeadAssetMode `Expected case name after 'case'` (10).
- USE CONST/FUNCTION IMPORTS (illegalstudio#473/EC-10/illegalstudio#493, namespace_use.rs): the lexer
  eagerly tokenizes `PHP_INT_MAX` etc., so the use-declaration parser must
  accept those dedicated tokens as import names (`use const PHP_INT_MAX;`).
  Clears RegionEntry `Expected imported name after 'use'` (2).

Deferred (not survey-visible on v0.26.1): illegalstudio#469 keyword-case access, illegalstudio#472 clone.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
chadmandoo added a commit to chadmandoo/elephc that referenced this pull request Jul 10, 2026
…opy (R9/#599, illegalstudio#472)

v0.26.1's parser rejected `clone $x` ("Expected ';'"), gapping every PSR-7
immutability wither (Message/Uri/RequestBehavior `$new = clone $this`). Re-ports
illegalstudio#472 (8485e9e) onto the post-EIR-refactor tree:

- PARSER: contextual `clone <expr>` prefix operator (clone is not a reserved
  token — `clone_operand_follows` guards it so a bare identifier spelled "clone"
  in a non-operator position still parses as a name). New ExprKind::Clone(Box<Expr>).
- CHECKER: `clone $x` infers as the type of `$x`.
- EIR: shallow object/array copy lowering (array_clone_shallow, x86 frame-safe).
- The new AST variant is threaded through every ExprKind match (name resolver,
  optimizer passes, magic-constant walker, usage/invalidation analysis, warnings).
  The legacy backend is gone in v0.26.1, so no legacy emit arm is needed.

clone codegen tests pass (round-trip + contextual-keyword). Survey 90% → 91%
(277 → 278/307); the "Expected ';'" gaps (Message ×4, Uri, RequestBehavior) clear.
Also completes R6's deferred illegalstudio#472.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
chadmandoo added a commit to chadmandoo/elephc that referenced this pull request Jul 11, 2026
…opy (R9/#599, illegalstudio#472)

v0.26.1's parser rejected `clone $x` ("Expected ';'"), gapping every PSR-7
immutability wither (Message/Uri/RequestBehavior `$new = clone $this`). Re-ports
illegalstudio#472 (8485e9e) onto the post-EIR-refactor tree:

- PARSER: contextual `clone <expr>` prefix operator (clone is not a reserved
  token — `clone_operand_follows` guards it so a bare identifier spelled "clone"
  in a non-operator position still parses as a name). New ExprKind::Clone(Box<Expr>).
- CHECKER: `clone $x` infers as the type of `$x`.
- EIR: shallow object/array copy lowering (array_clone_shallow, x86 frame-safe).
- The new AST variant is threaded through every ExprKind match (name resolver,
  optimizer passes, magic-constant walker, usage/invalidation analysis, warnings).
  The legacy backend is gone in v0.26.1, so no legacy emit arm is needed.

clone codegen tests pass (round-trip + contextual-keyword). Survey 90% → 91%
(277 → 278/307); the "Expected ';'" gaps (Message ×4, Uri, RequestBehavior) clear.
Also completes R6's deferred illegalstudio#472.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chadmandoo
chadmandoo force-pushed the upstream-pr/clone-operator branch from 8983e58 to 9adf5fb Compare July 11, 2026 13:47
@chadmandoo
chadmandoo force-pushed the upstream-pr/clone-operator branch from 9adf5fb to 1df2b24 Compare July 11, 2026 13:53
@github-actions github-actions Bot added area:codegen Touches target-aware assembly or backend lowering. area:optimizer Touches AST or EIR optimization passes. area:types Touches type checking, inference, or compatibility. scope:multi-area Touches more compiler areas than the automatic area-label cap. size:l Large pull request. type:feature Introduces new user-visible behavior or capabilities. labels Jul 13, 2026
@nahime0

nahime0 commented Jul 19, 2026

Copy link
Copy Markdown
Member

Closing as superseded by main.

clone already landed on main (notably 5d0536c00 “Add object clone support”) with the rigorous path this PR only sketched: retained heap-backed property slots, stdClass/dynamic-property hash cloning, and __clone() invocation with visibility checks.

Relative to current main this branch does not add a useful implementation delta. The shallow wordwise payload copy without retain, plus hard-rejecting __clone() and dynamic-properties classes, are workarounds rather than the ownership/runtime model elephc needs. Main already covers the intended semantics (and more); the only possibly reusable bits are a couple of test fixtures (PSR-7 wither round-trip / contextual clone($x) + method named clone), which can be ported separately if desired.

Thanks a lot for the contribution.

@nahime0 nahime0 closed this Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:codegen Touches target-aware assembly or backend lowering. area:optimizer Touches AST or EIR optimization passes. area:types Touches type checking, inference, or compatibility. scope:multi-area Touches more compiler areas than the automatic area-label cap. size:l Large pull request. type:feature Introduces new user-visible behavior or capabilities.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants